package  
{
	import adobe.utils.CustomActions;
	import flash.events.MouseEvent;
	/**
	 * ...
	 * @author patsup
	 * 
	 * 		This class handles the rolling of the dice (DieObjects).
	 * The subset sum problem algorithm is contained in this class.
	 * 
	 */
	public class DiceArea extends Button 
	{
		private var diceMaxValue:int;
		private var diceValue:int = 0;				//the current value of the dice
		private var dice:Vector.<DieObject>;
		
		private var gameRef:PGame;
		
		//temporary die and dice area image parameters
		private const DICE_AREA_COLOR:int = 0x000000;
		private const DICE_AREA_ALPHA:Number = 0.1;
		private const DICE_AREA_WIDTH:int = 140;
		private const DICE_AREA_HEIGHT:int = 50;
		private const DIE_WIDTH:int = 30;
		private const DIE_HEIGHT:int = 30;
		
		private const DIE_SPACING:int = 50;
		
		public function DiceArea(gameRef:PGame, numberOfDice:int, diceSize:int, xCoord:int, yCoord:int) 
		{
			name = "Dice Area";
			this.gameRef = gameRef;
			diceMaxValue = diceSize;
			
			dice = new Vector.<DieObject>;
			for (var i:int = 0; i < numberOfDice;i++)
			{
				var _die:DieObject = new DieObject(diceSize, DIE_WIDTH, DIE_HEIGHT, DIE_SPACING * i, 0);
				dice.push(_die);
				addChild(_die);
			}
			
			
			//WHEN DO I INITIALIZE THE VALUE OF diceValue ????????????
			//for (i = 0; i < numberOfDice;i++)
			//{
				//dice[i].rollDie();
			//}
			
			
			//the following shouldn't go here???  used in CheckEnd() and subset()
			w = new Vector.<int>;
			xx = new Vector.<int>;
			
			InitImage();
			Initialize();
			super(xCoord, yCoord);
		}
		
		//Initialize()
		//Initializes the creation of the DiceArea
		public override function Initialize():void
		{
			InitInput();
			
			super.Initialize();
		}
		
		//InitImage()
		//Initializes the image of the DiceArea
		protected override function InitImage():void
		{
			graphics.beginFill(DICE_AREA_COLOR, DICE_AREA_ALPHA);
			graphics.drawRect(0, 0, DICE_AREA_WIDTH, DICE_AREA_HEIGHT);
			graphics.endFill();
			super.InitImage();
		}
		
		//InputMouseClick()
		//Takes action for DiceArea upon hearing the mouseclick event
		//Stop the dice from "rolling"
		protected override function InputMouseClick(e:MouseEvent):void
		{
			var _total:int = 0;
			for each (var _die:DieObject in dice)
			{
				_total += _die.RollDie();			//roll the die, and calculate running total
			}
			diceValue = _total;
			
			DisableButton();						//make button unclickable (dice can't be rolled)
			gameRef.ExecuteSubRound();				//incr number of tries, update session stats text
			gameRef.EnableExecute();				//let execute be clickable
			gameRef.EnablePirates();				//let pirates be clickable
			
			CheckEnd();
			
			super.InputMouseClick(e);
		}
		
		//GetDiceValue()
		//Returns the total value of the dice
		public function GetDiceValue():int
		{
			return diceValue;
		}
		
		
		//variables used for sum of subset() algorithm
		private var count:int = 0;
		private var d:int;				//target value
		private var w:Vector.<int>;		//holds elements
		private var xx:Vector.<int>;
		private function subset(cs:int, k:int, r:int):void
		{
			var i:int;
			xx[k] = 1;
			//trace("subset: " + cs + " " + w[i] + " " + k + " " + r + " " + d);
			if (cs + w[k] == d)
			{
				++count;
				trace(" Subset solution #" + count);
				for (i = 0; i <= k; i++)
				{
					if (xx[i] == 1 && (i<w.length)) {
						trace(w[i]);
					}
				}
			} else if ((k+1<w.length) && (cs + w[i] + w[k + 1]) <= d) {
				subset(cs + w[k], k + 1, r - w[k]);
			}
			if ((k+1<w.length) && (cs + r - w[k] >= d) && (cs + w[k + 1]) <= d) {
				xx[k] = 0;
				subset(cs, k + 1, r - w[k]);
			}
			
		}

		//CompareInts()
		//comparison function used for sorting vector in subset()
		private function CompareInts(x:int, y:int):Number {
			if (x < y) return -1;
			if (x > y) return 1;
			return 0;
		}
		
		//CheckEnd()
		//checks if there are any possible combinations of pirates to fulfill a possible solution
		//if not, then it's the end of the game
		//calls subset() using a "sum of subset" algorithm
		private function CheckEnd():void
		{
			var sum:int = 0;
			var i:int = 0;
			var n:int = gameRef.NumPirates();
			
			for (i = 0; i < n; i++) {	//initialize vectors
				w.push(gameRef.GetPirateValueAt(i));
				xx.push(0);
			}
			w.sort(CompareInts);
			w.push(0);					//need to tack on additional items at the end for use in subset() i think
			xx.push(0);
			
			for (i = 0; i < n; i++) {
				sum += w[i];
			}
			d = diceValue;
			if (sum < d) {
				gameRef.EndRound(0);		// <<<END OF ROUND>>>  0 = round lost
			} else {
				count = 0;
				subset(0, 0, sum);
				if (count == 0)
					gameRef.EndRound(0);	// <<<END OF ROUND>>>  0 = round lost
			}
			while (w.length > 0) w.pop();	//clear out vectors since they'll be repopulated next time
			while (xx.length > 0) xx.pop();
			
		}
		

	}

}